#include <REGX52.H>
/**
 * 菜单控制LED
 * 1. 正向流水灯
 * 2. 反向流水灯
 * 3. 正向计时功能
 * 4. 倒计时功能
 *
 * 功能模式按键，菜单前进按键，菜单后退按键
 */

#define LED_DATA P2

/**
 * 0：选择模式
 * >=1 ：对应功能的模式
 */

unsigned char mode = 0;
// 选择的菜单编号
unsigned char menu = 1;

sbit BTN_MODE = P3 ^ 0;
sbit BTN_LEFT = P3 ^ 1;
sbit BTN_RIGHT = P3 ^ 2;

#define PRESSED_MODE 1
#define PRESSED_LEFT 2
#define PRESSED_RIGHT 3
#define PRESSED_NONE 0

#define MODE_SELECTION 0
#define MODE_FLOWING_LIGHT 1
#define MODE_FLOWING_LIGHT_BACKWARD 2
#define MODE_TIMER 3
#define MODE_TIMER_BACKWARD 4

#define MENU_MAX 4

void delay_ms(unsigned int ms)
{
    unsigned int i, j;
    for (i = 0; i < ms; i++)
    {
        for (j = 0; j < 123; j++)
            ;
    }
}

unsigned char press_button()
{
    if (BTN_MODE == 0)
    {
        while (BTN_MODE == 0)
        {
        }

        return PRESSED_MODE;
    }
    if (BTN_LEFT == 0)
    {
        while (BTN_LEFT == 0)
        {
        }

        return PRESSED_LEFT;
    }

    if (BTN_RIGHT == 0)
    {
        while (BTN_RIGHT == 0)
        {
        }

        return PRESSED_RIGHT;
    }

    return PRESSED_NONE;
}

void select_mode()
{
    unsigned char press;
    LED_DATA = ~menu;
    while (mode == MODE_SELECTION)
    {
        press = press_button();
        switch (press)
        {
        case PRESSED_MODE:
            // menu数字和模式一一对应
            mode = menu;
            break;
        case PRESSED_LEFT:
            menu--;
            if (menu == 0)
            {
                menu = MENU_MAX;
            }
            LED_DATA = ~menu;
            break;
        case PRESSED_RIGHT:
            menu++;
            if (menu > MENU_MAX)
            {
                menu = 1;
            }
            LED_DATA = ~menu;
            break;
        default:
            break;
        }
    }
}

/**
 * 1: 进入到模式选择
 * 0：没有进入到模式选择
 */
bit check_mode_selection_on()
{
    if (press_button() == PRESSED_MODE)
    {
        mode = MODE_SELECTION;
        return 1;
    }

    return 0;
}

void flowing_light()
{
    unsigned char i;
    unsigned char temp = 0x80;
    while (mode == MODE_FLOWING_LIGHT)
    {
        temp = 0x80;
        LED_DATA = ~temp;
        delay_ms(500);
        for (i = 0; i < 7; i++)
        {
            if (check_mode_selection_on())
            {
                break;
            }
            temp >>= 1;
            LED_DATA = ~temp;
            delay_ms(500);
        }
    }
}

void flowing_light_backward()
{
    unsigned char i;
    unsigned char temp = 0x01;
    while (mode == MODE_FLOWING_LIGHT_BACKWARD)
    {
        temp = 0x01;
        LED_DATA = ~temp;
        delay_ms(500);
        for (i = 0; i < 7; i++)
        {
            if (check_mode_selection_on())
            {
                break;
            }
            temp <<= 1;
            LED_DATA = ~temp;
            delay_ms(500);
        }
    }
}

unsigned char num_count = 0;
void timer()
{
    while (mode == MODE_TIMER)
    {
        num_count++;
        LED_DATA = ~num_count;
        delay_ms(500);
        if (check_mode_selection_on())
        {
            break;
        }
    }
}

void timer_backward()
{
    while (mode == MODE_TIMER_BACKWARD)
    {
        num_count--;
        LED_DATA = ~num_count;
        delay_ms(500);
        if (check_mode_selection_on())
        {
            break;
        }
    }
}

void main()
{
    while (1)
    {
        switch (mode)
        {
        case MODE_SELECTION:
            select_mode();
            break;
        case MODE_FLOWING_LIGHT:
            flowing_light();
            break;
        case MODE_FLOWING_LIGHT_BACKWARD:
            flowing_light_backward();
            break;
        case MODE_TIMER:
            timer();
            break;
        case MODE_TIMER_BACKWARD:
            timer_backward();
            break;
        default:
            break;
        }
    }
}